#ifndef VERTEX_HPP
#define VERTEX_HPP

#include <cstdlib>
#include <cstdio>
#include <cstring>

#include <set>
#include <iostream>
#include "Types.hpp"

class Vertex
{
public:
    Vertex(const real (&coordinates)[DIM]);
    Vertex(const Vertex& copy);
    Vertex(){std::cout<<"DEFAULT_VERTEX\n";}

    ~Vertex(){}

    Vertex& operator=(const Vertex& copy);

    inline const real& getCoordinate(const size_t& axis) const {return coordinates_[axis];}
    inline const std::set<size_t>& getNeighborIDs() const {return neighbor_ids_;}

    inline void setCoordinate(const size_t& axis, const real& value){coordinates_[axis]=value;}
    inline void addNeighborID(const size_t& nid){neighbor_ids_.insert(nid);}
    inline bool isEqual(const Vertex & other) { bool ret = true; size_t i =0; while (ret && i <2) { if (this->coordinates_[i] != other.coordinates_[i]) ret = false; break; } ++i; return ret;}

    inline void setbdFlag() { if (neighbor_ids_. size() <=4) bdFlag_ = 1; else bdFlag_ =0;}
    inline void setbdFlag(const int& Flag) { bdFlag_ = Flag;}
    //  inline const int getbdFlag const( return bdFlag_;)
    inline bool isBoundary() { if (bdFlag_ ==1) return true; else return false;}
private:
    real coordinates_[DIM];
    std::set<size_t> neighbor_ids_;
    int bdFlag_;

};

struct Face
{
    size_t vertexIDs_[N_FACE_VERTEX];
    Face(const size_t (&vertexIDs)[N_FACE_VERTEX])
    {
        for(size_t i(0);i<N_FACE_VERTEX;++i){
            vertexIDs_[i]=vertexIDs[i];
        }
    }
};

struct Segment
{
    size_t id1;
    size_t id2;
    int midPointId;
    Segment(const size_t& nID1, const size_t& nID2):id1(nID1),id2(nID2),midPointId(-1){}
    Segment(){std::cout<<"DEFAULT SEGMENT";}
    bool sameSegment(const size_t& nID1, const size_t& nID2)
    {
        return ((id1==nID1 && id2==nID2)||(id1==nID2 && id2==nID1))?true:false;
    }

};

Vertex::Vertex(const real (&coordinates)[DIM])
{
    for(size_t i(0);i<DIM;++i)
        coordinates_[i]=coordinates[i];
}

Vertex::Vertex(const Vertex& copy)
{
    for(size_t i(0);i<DIM;++i)
        coordinates_[i]=copy.coordinates_[i];
    neighbor_ids_=copy.neighbor_ids_;
}

Vertex& Vertex::operator=(const Vertex& copy)
{
    for(size_t i(0);i<DIM;++i)
        coordinates_[i]=copy.coordinates_[i];
    neighbor_ids_=copy.neighbor_ids_;
    return *this;
}
#endif // VERTEX_HPP
